package com.bank.service;

import com.bank.entity.CardInfo;
import com.bank.entity.UserInfo;
import com.bank.entity.Deposit;
import com.bank.dto.CardInfoDTO;
import com.bank.repository.CardInfoRepository;
import com.bank.repository.UserInfoRepository;
import com.bank.repository.DepositRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Random;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Transactional
public class CardInfoService {
    @Autowired
    private CardInfoRepository cardInfoRepository;
    
    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private DepositRepository depositRepository;

    public CardInfo save(CardInfo cardInfo) {
        return cardInfoRepository.save(cardInfo);
    }

    public String generateCardId() {
        StringBuilder cardId = new StringBuilder("10103576");
        Random random = new Random();
        for (int i = 0; i < 9; i++) {
            cardId.append(random.nextInt(10));
        }
        return cardId.toString();
    }

    public java.util.Optional<CardInfo> findById(String cardId) {
        return cardInfoRepository.findById(cardId);
    }

    public java.util.List<CardInfo> findByKeyword(String keyword) {
        return cardInfoRepository.findByCardIDOrCustomerName(keyword);
    }

    public java.util.List<CardInfo> findAll() {
        return cardInfoRepository.findAll();
    }

    public void deleteById(String cardId) {
        cardInfoRepository.deleteById(cardId);
    }
    
    public List<CardInfoDTO> findAllWithCustomerName() {
        List<CardInfo> cards = cardInfoRepository.findAll();
        return convertToDTOs(cards);
    }
    
    public List<CardInfoDTO> findByKeywordWithCustomerName(String keyword) {
        List<CardInfo> cards = cardInfoRepository.findByCardIDOrCustomerName(keyword);
        return convertToDTOs(cards);
    }

    private List<CardInfoDTO> convertToDTOs(List<CardInfo> cards) {
        if (cards.isEmpty()) {
            return java.util.Collections.emptyList();
        }
        
        // 1. 高效获取所有需要的用户信息
        List<Long> userIds = cards.stream()
            .map(CardInfo::getCustomerID)
            .filter(java.util.Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
        Map<Long, UserInfo> userMap = userInfoRepository.findAllById(userIds).stream()
            .collect(Collectors.toMap(UserInfo::getCustomerID, Function.identity()));

        // 2. 高效获取所有需要的存款类型信息
        List<Long> savingIds = cards.stream()
            .map(CardInfo::getSavingID)
            .filter(java.util.Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
        Map<Long, Deposit> depositMap = depositRepository.findAllById(savingIds).stream()
            .collect(Collectors.toMap(Deposit::getSavingID, Function.identity()));
            
        // 3. 组装DTO
        return cards.stream().map(card -> {
            CardInfoDTO dto = new CardInfoDTO();
            dto.setCardID(card.getCardID());
            dto.setCurID(card.getCurID());
            dto.setSavingID(card.getSavingID());
            dto.setOpenDate(card.getOpenDate());
            dto.setOpenMoney(card.getOpenMoney());
            dto.setBalance(card.getBalance());
            dto.setPass(card.getPass());
            dto.setIsReportLoss(card.getIsReportLoss());
            dto.setCustomerID(card.getCustomerID());

            // 设置用户名
            if (card.getCustomerID() != null && userMap.containsKey(card.getCustomerID())) {
                dto.setCustomerName(userMap.get(card.getCustomerID()).getCustomerName());
            } else {
                dto.setCustomerName(card.getCustomerName()); // Fallback
            }

            // 设置存款类型名
            if (card.getSavingID() != null && depositMap.containsKey(card.getSavingID())) {
                dto.setSavingName(depositMap.get(card.getSavingID()).getSavingName());
            } else {
                dto.setSavingName("未知类型");
            }
            
            return dto;
        }).collect(Collectors.toList());
    }

    public Long generateRandomCustomerId() {
        return System.currentTimeMillis();
    }

    // 同步用户姓名到所有银行卡
    public void syncCustomerNameToCards(Long customerID, String customerName) {
        cardInfoRepository.updateCustomerNameByCustomerID(customerID, customerName);
    }

    public void deleteByCustomerID(Long customerID) {
        cardInfoRepository.deleteByCustomerID(customerID);
    }
} 